var ajaxFileUploadDebug = false;

( function($) {
	$.fn.ajaxFileUpload = function(options) {
		var defaults = {
			url : "upload.php",
			name: 'userfile',
			dataType: "json",
			
			onSubmit: function(file, ext){}
		};
		var options = $.extend(defaults, options);
		
		return this.each( function() {
			$this = $(this);
			if($this.is("input[type='file']")){
				$this.bind("change", options, function(e){
					$.fn.ajaxFileUpload.eventStartUpload($(this), e.data);
				})
			} else{
				//Buscaremos hijos de typo file...
			}
		});

	};
	
	$.fn.ajaxFileUpload.eventStartUpload = function(elem, options){
		$t = elem;

		var result = options.onSubmit($.fn.ajaxFileUpload.getFileName($t.val()), $.fn.ajaxFileUpload.getFileExtension($t.val()));

		//Tendremos que limpiar nuevamente el input si falla...
		if(result != false){		
			var id = new Date().getTime()  ;      
			var form = $.fn.ajaxFileUpload.createUploadForm(id, $t, options);
			var io = $.fn.ajaxFileUpload.createUploadIframe(id, options.secureuri);
			var frameId = 'jUploadFrame' + id;
			var formId = 'jUploadForm' + id;		
	        // Watch for a new set of requests
	        if ( options.global && ! $.active++ )
			{
				$.event.trigger( "ajaxStart" );
			}            
	        var requestDone = false;
	        // Create the request object
	        var xml = {}   
	        if ( options.global )
	            $.event.trigger("ajaxSend", [xml, options]);
	        
	        // Wait for a response to come back
	        var uploadCallback = function(isTimeout)
			{			
				var io = document.getElementById(frameId);
	            try 
				{				
					if(io.contentWindow)
					{
						 xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
	                	 xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
						 
					}else if(io.contentDocument)
					{
						 xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
	                	xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
					}						
	            }catch(e)
				{
					$.handleError(options, xml, null, e);
				}
	            if ( xml || isTimeout == "timeout") 
				{				
	                requestDone = true;
	                var status;
	                try {
	                    status = isTimeout != "timeout" ? "success" : "error";
	                    // Make sure that the request was successful or notmodified
	                    if ( status != "error" )
						{
	                        // process the data (runs the xml through httpData regardless of callback)
	                        var data = $.fn.ajaxFileUpload.uploadHttpData( xml, options.dataType );    
	                        // If a local callback was specified, fire it and pass it the data
	                        if ( options.success )
	                            options.success($.fn.ajaxFileUpload.getFileName($t.val()), data, status );
	    
	                        // Fire the global callback
	                        if( options.global )
	                            $.event.trigger( "ajaxSuccess", [xml, options] );
	                    } else
	                        $.handleError(options, xml, status);
	                } catch(e) 
					{
	                    status = "error";
	                    $.handleError(options, xml, status, e);
	                }
	
	                // The request was completed
	                if( options.global )
	                    $.event.trigger( "ajaxComplete", [xml, options] );
	
	                // Handle the global AJAX counter
	                if ( options.global && ! --$.active )
	                    $.event.trigger( "ajaxStop" );
	
	                // Process result
	                if ( options.complete )
	                    options.complete(xml, status);
	
	                $(io).unbind()
	
	                setTimeout(function()
					{	try 
						{
							//$(io).remove();
							//$(form).remove();	
							
						} catch(e) 
						{
							$.handleError(options, xml, null, e);
						}									

					}, 100)
	
	                xml = null
	
	            }
	        }
	        // Timeout checker
	        if ( options.timeout > 0 ) 
			{
	            setTimeout(function(){
	                // Check to see if the request is still happening
	                if( !requestDone ) uploadCallback( "timeout" );
	            }, options.timeout);
	        }
	        try 
			{
	           // var io = $('#' + frameId);
				var form = $('#' + formId);
				$(form).attr('action', options.url);
				
				//alert(options.url);
				
				$(form).attr('method', 'POST');
				$(form).attr('target', frameId);
	            if(form.encoding)
				{
	                form.encoding = 'multipart/form-data';				
	            }
	            else
				{				
	                form.enctype = 'multipart/form-data';
	            }			
	            $(form).submit();
	
	        } catch(e) 
			{			
	            $.handleError(options, xml, null, e);
	        }
	        if(window.attachEvent){
	            document.getElementById(frameId).attachEvent('onload', uploadCallback);
	        }
	        else{
	            document.getElementById(frameId).addEventListener('load', uploadCallback, false);
	        } 		
	        return {abort: function () {}};	
		}
	},
	
	$.fn.ajaxFileUpload.createUploadIframe = function(id, uri){
		//create frame
        var frameId = 'jUploadFrame' + id;
        
        if(window.ActiveXObject) {
            var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
            if(typeof uri== 'boolean'){
                io.src = 'javascript:false';
            }
            else if(typeof uri== 'string'){
                io.src = uri;
            }
        }
        else {
            var io = document.createElement('iframe');
            io.id = frameId;
            io.name = frameId;
        }
        
        io.style.position = 'absolute';
        io.style.background = "#FFF";
        io.style.top = '-1000px';
        io.style.left = '-1000px';
        
        if(ajaxFileUploadDebug){
        	io.style.top = '0px';
            io.style.left = '0px';
        }
        
        document.body.appendChild(io);

        return io;
    },
    $.fn.ajaxFileUpload.createUploadForm = function(id, element, options){
		//create form	
		var formId = 'jUploadForm' + id;
		var fileId = 'jUploadFile' + id;
		var form = $('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');	
		var oldElement = $(element);
		oldElement.unbind("change");
		
		var newElement = $(oldElement).clone();
		
		newElement.attr("value", "");
		newElement.change(function(){
			$.fn.ajaxFileUpload.eventStartUpload($(this), options);				
		});
		
		$(oldElement).attr('id', '');
		$(oldElement).removeAttr('disabled');
		$(oldElement).before(newElement);
		
		$(oldElement).appendTo(form);
		oldElement.attr("name", options.name);
		
		//set attributes
		$(form).css('position', 'absolute');
		$(form).css('top', '-1200px');
		$(form).css('left', '-1200px');
		
		if(ajaxFileUploadDebug){
			$(form).css('top', '30px');
			$(form).css('left', '0px');
        }
		
		$(form).appendTo('body');		
		
		return form;
    },
    $.fn.ajaxFileUpload.uploadHttpData = function( r, type ) {
        var data = !type;
        data = type == "xml" || data ? r.responseXML : r.responseText;
        // If the type is "script", eval it in global context
        if ( type == "script" )
            $.globalEval( data );
        // Get the JavaScript object, if JSON is used.
        if ( type == "json" )
            eval( "data = " + data );
        // evaluate scripts within html
        if ( type == "html" )
            $("<div>").html(data).evalScripts();
			//alert($('param', data).each(function(){alert($(this).attr('value'));}));
        return data;
    },
    
    $.fn.ajaxFileUpload.getFileName = function(file){
    	return file.replace(/.*(\/|\\)/, "");
    },
	
    $.fn.ajaxFileUpload.getFileExtension = function(file){
    	return (/[.]/.exec(file)) ? /[^.]+$/.exec(file.toLowerCase()) : '';
    }
	
	
})(jQuery);
